﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace neside3
{
    public static partial class IDE
    {
        public class ProjOption
        {
            public string buildtype;
            public Newtonsoft.Json.Linq.JToken buildoption;
            public string runner;
            public string description;
            public static ProjOption FromFile(string filename)
            {
                var text = System.IO.File.ReadAllText(filename);
                var json = Newtonsoft.Json.Linq.JObject.Parse(text);
                ProjOption opt = new ProjOption();
                opt.buildtype = json["buildtype"].ToString();
                opt.buildoption = json["buildoption"];
                opt.description = json["description"].ToString();
                opt.runner = json["runner"]?.ToString();
                return opt;
            }
        }
        static List<neside3.ext.IFileEditor> plugin_editor = new List<ext.IFileEditor>();
        static Dictionary<string, int> mapext2editor = new Dictionary<string, int>();
        static Dictionary<string, ext.IRunner> plugin_runner = new Dictionary<string, ext.IRunner>();
        static Dictionary<string, ext.IBuilder> plugin_builder = new Dictionary<string, ext.IBuilder>();

        public static ext.ILogger logger
        {
            get;
            private set;
        }
        public static void InitPlugin(ext.ILogger _logger)
        {
            logger = _logger;
            var pdo = AppDomain.CreateDomain("plugindomain");
            var file = System.IO.Directory.GetFiles("plugin", "*.dll");
            foreach (var f in file)
            {
                var name = System.Reflection.AssemblyName.GetAssemblyName(f);
                var ass = System.Reflection.Assembly.Load(name);
                foreach (var t in ass.GetTypes())
                {
                    foreach (var i in t.GetInterfaces())
                    {
                        if (i.FullName == typeof(ext.IFileEditor).FullName)
                        {//fileeditor 初始化
                            try
                            {
                                var editor = t.GetConstructor(new Type[0]).Invoke(null) as ext.IFileEditor; ;
                                plugin_editor.Add(editor);
                                foreach (var ext in editor.extName)
                                {
                                    mapext2editor[ext] = plugin_editor.Count - 1;
                                }
                                logger.Warn("Load Plugin:" + t.Name + " from:" + f);
                                break;
                            }
                            catch
                            {

                            }
                        }
                        if (i.FullName == typeof(ext.IRunner).FullName)
                        {//runner初始化
                            try
                            {
                                var runner = t.GetConstructor(new Type[0]).Invoke(null) as ext.IRunner; ;
                                plugin_runner.Add(runner.RunnerType, runner);
                                logger.Warn("Load Plugin:" + t.Name + " from:" + f);
                                break;
                            }
                            catch
                            {

                            }
                        }
                        if (i.FullName == typeof(ext.IBuilder).FullName)
                        {//builder 初始化
                            try
                            {
                                var builder = t.GetConstructor(new Type[0]).Invoke(null) as ext.IBuilder; ;
                                plugin_builder.Add(builder.BuilderType, builder);
                                logger.Warn("Load Plugin:" + t.Name + " from:" + f);
                                break;
                            }
                            catch
                            {

                            }
                        }
                    }

                }
                // var ass = pdo.Load(name);

            }
        }
        static UIElement func_edit;
        static UIElement func_play;
        public static UIElement getUI_func_edit()
        {
            if (func_edit == null)
                func_edit = new func_edit.panel_project();
            return func_edit;
        }

        public static UIElement getUI_func_play()
        {
            return null;
        }
        public static string curProject_Folder
        {
            get;
            private set;
        }
        public static IDE.ProjOption GetCurProject_Option()
        {
            var config = System.IO.Path.Combine(curProject_Folder, "neside.json");
            if (System.IO.File.Exists(config) == false)
                return null;
            var curProject_Option = IDE.ProjOption.FromFile(config);
            return curProject_Option;
        }
        static FileSystemWatcher watcher;
        public static event Action<string, string> onFileListChange;
        static void InitWatcher()
        {
            if (watcher == null)
            {
                watcher = new FileSystemWatcher();
                watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
                watcher.Created += (s, e) =>
                {
                    onFileListChange?.Invoke(watcher.Path, e.FullPath);
                };
                watcher.Deleted += (s, e) =>
                {
                    onFileListChange?.Invoke(watcher.Path, e.FullPath);

                    Documents.OutChange(watcher.Path, e.FullPath, true);
                };
                watcher.Renamed += (s, e) =>
                {
                    onFileListChange?.Invoke(watcher.Path, e.FullPath);
                    Documents.OutChange(watcher.Path, e.FullPath, true);
                };
                watcher.Changed += (s, e) =>
                {
                    Documents.OutChange(watcher.Path, e.FullPath, false);
                };
                watcher.IncludeSubdirectories = true;

            }
        }
        public static void OpenProject(string folder)
        {
            foreach (var p in plugin_editor)
            {
                p.SetProject(logger, folder);
            }
            foreach (var p in plugin_builder.Values)
            {
                p.SetProject(logger, folder);
            }
            foreach (var p in plugin_runner.Values)
            {
                p.SetProject(logger, folder);
            }
            var config = System.IO.Path.Combine(folder, "neside.json");
            //curProject_Option = IDE.ProjOption.FromFile(config);
            curProject_Folder = folder;

            //打开文件，并监视文件变化
            InitWatcher();
            watcher.Path = folder;
            watcher.EnableRaisingEvents = true;
        }
    }
}
